<template>
	<div class="app-container">
		<el-input class="search-box" placeholder="请输入关键词" v-model="listQuery.keyword">
		</el-input>

		<el-select v-model="listQuery.field" placeholder="请选择搜索字段">
			<el-option v-for="item in fieldOptions" :key="item.value" :label="item.label" :value="item.value">
			</el-option>
		</el-select>
		<el-button type="primary" icon="el-icon-search" @click="handleQuery">
			搜索
		</el-button>
		<el-button type="primary" icon="el-icon-edit" @click="handleAdd">
			添加
		</el-button>
		<el-button type="primary" icon="el-icon-upload" @click="uploadFile">
			导入
		</el-button>
		<el-button type="primary" icon="el-icon-download" @click="downloadFile">
			导出
		</el-button>
		<el-button type="primary" icon="el-icon-document" @click="downloadTemplate">
			模板下载
		</el-button>

		<a id="downlink" ref="outFile"></a>
		<input type="file" @change="importFile(this)" ref="imFile" style="display:none" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" />

		<el-table :data="staffList" stripe border style="width: 100%" v-loading="listLoading">
			<el-table-column prop="number" label="员工序号">
			</el-table-column>

			<el-table-column label="用户名">
				<template slot-scope="scope">
					<el-input v-if="scope.row.editable" v-model="scope.row.username" placeholder=""></el-input>
					<span v-else>{{ scope.row.username }}</span>
				</template>
			</el-table-column>

			<el-table-column label="密码">
				<template slot-scope="scope">
					<el-input v-if="scope.row.editable" v-model="scope.row.password" placeholder=""></el-input>
					<span v-else>{{ scope.row.password }}</span>
				</template>
			</el-table-column>

			<el-table-column label="真实姓名">
				<template slot-scope="scope">
					<el-input v-if="scope.row.editable" v-model="scope.row.realname" placeholder=""></el-input>
					<span v-else>{{ scope.row.realname }}</span>
				</template>
			</el-table-column>

			<el-table-column label="部门名称">
				<template slot-scope="scope">
					<el-input v-if="scope.row.editable" v-model="scope.row.branchName" placeholder=""></el-input>
					<span v-else>{{ scope.row.branchName }}</span>
				</template>
			</el-table-column>

			<el-table-column label="邮箱">
				<template slot-scope="scope">
					<el-input v-if="scope.row.editable" v-model="scope.row.email" placeholder=""></el-input>
					<span v-else>{{ scope.row.email }}</span>
				</template>
			</el-table-column>

			<el-table-column label="手机号码">
				<template slot-scope="scope">
					<el-input v-if="scope.row.editable" v-model="scope.row.mobile" placeholder=""></el-input>
					<span v-else>{{ scope.row.mobile }}</span>
				</template>
			</el-table-column>

			<el-table-column label="座机电话">
				<template slot-scope="scope">
					<el-input v-if="scope.row.editable" v-model="scope.row.companyTel" placeholder=""></el-input>
					<span v-else>{{ scope.row.companyTel }}</span>
				</template>
			</el-table-column>

			<el-table-column label="职位">
				<template slot-scope="scope">
					<el-input v-if="scope.row.editable" v-model="scope.row.position" placeholder=""></el-input>
					<span v-else>{{ scope.row.position }}</span>
				</template>
			</el-table-column>

			<el-table-column label="备注">
				<template slot-scope="scope">
					<el-input v-if="scope.row.editable" v-model="scope.row.comments" placeholder=""></el-input>
					<span v-else>{{ scope.row.comments }}</span>
				</template>
			</el-table-column>

			<el-table-column label="操作" width="160" align="center">
				<template slot-scope="scope">
					<div class="button-wrapper" v-if="scope.row.editable">
						<el-button size="small" type="success" @click="handleConfirm(scope.$index, scope.row)">
							确认
						</el-button>
						<el-button size="small" type="danger" @click="handleCancel(scope.$index, scope.row)">
							取消
						</el-button>
					</div>
					<div class="button-wrapper" v-else>
						<el-button size="small" type="warning" @click="handleEdit(scope.$index, scope.row)">
							编辑
						</el-button>
						<el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)">
							删除
						</el-button>
					</div>
				</template>
			</el-table-column>

		</el-table>

		<div class="pagination-container">
			<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-sizes="[20, 40, 100]" :page-size="listQuery.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total">
			</el-pagination>
		</div>

		<el-dialog title="添加" :visible.sync="dialogFormVisible" width="400px">
			<el-form :rules="rules" :model="newStaff" label-width="120" ref="newStaffForm" size="small">
				<el-form-item label="员工序号" prop="number">
					<el-input v-model="newStaff.number"></el-input>
				</el-form-item>
				<el-form-item label="用户名" prop="username">
					<el-input v-model="newStaff.username"></el-input>
				</el-form-item>
				<el-form-item label="密码" prop="password">
					<el-input v-model="newStaff.password"></el-input>
				</el-form-item>
				<el-form-item label="真实姓名" prop="realname">
					<el-input v-model="newStaff.realname"></el-input>
				</el-form-item>
				<el-form-item label="部门名称" prop="branchName">
					<el-input v-model="newStaff.branchName"></el-input>
				</el-form-item>
				<el-form-item label="邮箱" prop="email">
					<el-input v-model="newStaff.email"></el-input>
				</el-form-item>
				<el-form-item label="手机号码" prop="mobile">
					<el-input v-model="newStaff.mobile"></el-input>
				</el-form-item>
				<el-form-item label="座机电话" prop="companyTel">
					<el-input v-model="newStaff.companyTel"></el-input>
				</el-form-item>
				<el-form-item label="职位" prop="position">
					<el-input v-model="newStaff.position"></el-input>
				</el-form-item>
				<el-form-item label="备注" prop="comments">
					<el-input v-model="newStaff.comments"></el-input>
				</el-form-item>
			</el-form>
			<div slot="footer" class="dialog-footer">
				<el-button @click="dialogFormVisible = false">取 消</el-button>
				<el-button type="primary" @click="addStaff">确 定</el-button>
			</div>
		</el-dialog>
	</div>

</template>

<script>
	import { fetchStaffList, addStaff, updateStaff, deleteStaff, importStaff } from '@/api/staffs'
	var XLSX = require('xlsx')

	export default {
		data() {
			return {
				staffList: [],
				listQuery: {
					pageNum: 1,
					pageSize: 20,
					type: '',
					keyword: '',
					field: 'realname'
				},
				total: 0,
				fieldOptions: [{
						value: 'username',
						label: '用户名'
					},
					{
						value: 'realname',
						label: '真实姓名'
					},
					{
						value: 'mobile',
						label: '手机号码'
					}
				],
				listLoading: true,
				currentPage: 1,
				dialogFormVisible: false,
				newStaff: {
					number: '',
					username: '',
					password: '',
					realname: '',
					branchName: '',
					email: '',
					mobile: '',
					companyTel: '',
					position: '',
					comments: ''
				},
				rules: {
					number: [{
						required: true,
						message: '请填写员工序号',
						trigger: 'change'
					}],
					username: [{
						required: true,
						message: '请填写用户名',
						trigger: 'change'
					}],
					password: [{
						required: true,
						message: '请填写密码',
						trigger: 'change'
					}],
					realname: [{
						required: true,
						message: '请填写真实姓名',
						trigger: 'change'
					}],
					branchName: [{
						required: true,
						message: '请填写部门名称',
						trigger: 'change'
					}],
					email: [{
						required: true,
						message: '请填写邮箱',
						trigger: 'change'
					}],
					mobile: [{
						required: true,
						message: '请填写手机号码',
						trigger: 'change'
					}],
					companyTel: [{
						required: true,
						message: '请填写座机电话',
						trigger: 'change'
					}],
					position: [{
						required: true,
						message: '请填写职位',
						trigger: 'change'
					}],
					comments: [{
						required: true,
						message: '请填写备注',
						trigger: 'change'
					}]
				},
				fullscreenLoading: false,
				rABS: true
			}
		},
		methods: {
			getList() {
				this.listLoading = true
				return fetchStaffList(this.listQuery).then(res => {
					this.staffList = res.data.staffs.map(val => {
						// 保存一份原有值,在取消更改时使用
						for(var key in val) {
							if(key != 'id' && key != 'number') {
								// 旧值的key以_开头
								val[`_${key}`] = val[key]
							}
						}
						val.editable = false
						return val
					})
					this.total = res.data.totalCount
					this.listLoading = false
				})
			},
			handleQuery() {
				this.listQuery.type = 'query'
				this.getList()
			},
			handleSizeChange(val) {
				this.listQuery.pageSize = val
				this.getList()
			},
			handleCurrentChange(val) {
				this.listQuery.pageNum = val
				this.getList()
			},
			resetTemp() {
				this.newStaff = {
					number: '',
					username: '',
					password: '',
					realname: '',
					branchName: '',
					email: '',
					mobile: '',
					companyTel: '',
					position: '',
					comments: ''
				}
			},
			// 确认编辑
			handleConfirm(index, row) {
				updateStaff(row.id).then(res => {
					row.editable = false
					this.$message.success('更改成功');
				})
			},
			// 取消编辑
			handleCancel(index, row) {
				for(var key in row) {
					// 跳过id,number和editable以及保存原值的key
					if(['id', 'number', 'editable'].indexOf(key) < 0 && key.indexOf('_') != 0) {
						row[key] === row[`_${key}`] ? true : row[key] = row[`_${key}`]
					}
				}
				row.editable = false
				this.$message('已取消更改')
			},
			handleEdit(index, row) {
				row.editable = true
			},
			handleDelete(index, row) {
				deleteStaff(row.id).then(res => {
					this.staffList.splice(index, 1)
					this.$message.success('已成功删除')
				})
			},
			handleAdd() {
				this.resetTemp()
				this.dialogFormVisible = true
				this.$nextTick(() => {
					this.$refs.newStaffForm.clearValidate()
				})
			},
			addStaff() {
				this.$refs.newStaffForm.validate((valid) => {
					if(valid) {
						this.dialogFormVisible = false
						addStaff(this.newStaff).then(res => {
							this.listQuery.pageNum = 1
							this.getList().then(res => {
								this.$message({
									message: '添加成功',
									type: 'success'
								});
							})
						})
					}
				})
			},
			// 点击导入按钮
			uploadFile() {
				this.$refs.imFile.click()
			},
			// 此处可以解析导入数据
			analyzeData: function(data) {
				return data
			},
			// 处理导入的数据
			dealFile: function(data) {
				this.$refs.imFile.value = ''
				importStaff(data).then(res => {
          this.listQuery.pageNum = 1
          this.getList()
        })
			},
			// 导入excel
			importFile() {
				this.fullscreenLoading = true
				this.$set(this.staffList,"editable",false)
				let obj = this.$refs.imFile
				if(!obj.files) {
					this.fullscreenLoading = false
					return
				}
				var f = obj.files[0]
				var reader = new FileReader()
				reader.onload = (e) => {
					var data = e.target.result
					if(this.rABS) {
						// 手动转化
						this.wb = XLSX.read(btoa(this.fixdata(data)), {
							type: 'base64'
						})
					} else {
						this.wb = XLSX.read(data, {
							type: 'binary'
						})
					}
					let json = XLSX.utils.sheet_to_json(this.wb.Sheets[this.wb.SheetNames[0]])
					console.log(json)
					// analyzeData: 解析导入数据
					this.dealFile(this.analyzeData(json))
					this.fullscreenLoading = false
				}
				if(this.rABS) {
					reader.readAsArrayBuffer(f)
				} else {
					reader.readAsBinaryString(f)
				}
			},

			// 点击导出按钮
			downloadFile() {
				fetchStaffList().then(res => {
					var rs = res.data.staffs
					let data = [{}]
					for(let k in rs[0]) {
						data[0][k] = k
					}
					data = data.concat(rs)
					this.downloadExl(data, '员工管理数据')
				})
			},
	// 导出到excel
	downloadExl(json, downName, type) {
			const uA = window.navigator.userAgent
			const isIE = /msie\s|trident\/|edge\//i.test(uA) && !!("uniqueID" in document || "documentMode" in document || ("ActiveXObject" in window) || "MSInputMethodContext" in window)
			let keyMap = [] // 获取键
			for(let k in json[0]) {
				keyMap.push(k)
			}
			console.info('keyMap', keyMap, json)
			let tmpdata = [] // 用来保存转换好的json
			json.map((v, i) => keyMap.map((k, j) => Object.assign({}, {
				v: v[k],
				position: (j > 25 ? this.getCharCol(j) : String.fromCharCode(65 + j)) + (i + 1)
			}))).reduce((prev, next) => prev.concat(next)).forEach(function(v) {
				tmpdata[v.position] = {
					v: v.v
				}
			})
			let outputPos = Object.keys(tmpdata) // 设置区域,比如表格从A1到D10
			let tmpWB = {
				SheetNames: ['mySheet'], // 保存的表标题
				Sheets: {
					'mySheet': Object.assign({},
						tmpdata, // 内容
						{
							'!ref': outputPos[0] + ':' + outputPos[outputPos.length - 1] // 设置填充区域
						})
				}
			}
			let tmpDown = new Blob([this.s2ab(XLSX.write(tmpWB, {
					bookType: (type === undefined ? 'xlsx' : type),
					bookSST: false,
					type: 'binary'
				} // 这里的数据是用来定义导出的格式类型
			))], {
				type: ''
			}) // 创建二进制对象写入转换好的字节流
			var href = URL.createObjectURL(tmpDown) // 创建对象超链接
			this.$refs.outFile.download = downName + '.xlsx' // 下载名称
			this.$refs.outFile.href = href // 绑定a标签
			if(isIE) {
				// 兼容IE11无法触发下载的问题
				navigator.msSaveBlob(tmpDown, '员工列表.xlsx');
			} else {
				this.$refs.outFile.click() // 模拟点击实现下载
			}
			setTimeout(function() { // 延时释放
				URL.revokeObjectURL(tmpDown) // 用URL.revokeObjectURL()来释放这个object URL
			}, 100)
		},
		s2ab: function(s) { // 字符串转字符流
			var buf = new ArrayBuffer(s.length)
			var view = new Uint8Array(buf)
			for(var i = 0; i !== s.length; ++i) {
				view[i] = s.charCodeAt(i) & 0xFF
			}
			return buf
		},
		getCharCol: function(n) { // 将指定的自然数转换为26进制表示。映射关系：[0-25] -> [A-Z]。
			let s = ''
			let m = 0
			while(n > 0) {
				m = n % 26 + 1
				s = String.fromCharCode(m + 64) + s
				n = (n - m) / 26
			}
			return s
		},
		fixdata: function(data) { // 文件流转BinaryString
			var o = ''
			var l = 0
			var w = 10240
			for(; l < data.byteLength / w; ++l) {
				o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))
			}
			o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
			return o
		},
		// 模板下载
		downloadTemplate() {
			var tmpData = [{
					username: 'username',
					password: 'password',
					realname: 'realname',
					branchName: 'branchName',
					email: 'email',
					mobile: 'mobile',
					companyTel: 'companyTel',
					position: 'position',
          avatar: 'avatar',
          nameAtoZ: 'nameAtoZ',
					comments: 'comments'
				},
				{
					username: '用户（唯一）',
					password: '密码',
					realname: '真实姓名',
					branchName: '部门ID（对应部门ID）',
					email: '邮箱（可选）',
					mobile: '手机号码（可选）',
					companyTel: '座机电话（可选）',
					position: '职位（可选）',
          avatar: 'avatar',
          nameAtoZ: 'nameAtoZ',
					comments: '备注'
				}
			]
			this.downloadExl(tmpData, '员工模板')
		}
	},
	created() {
		this.getList()
	},
	}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
	.app-container {
		.search-box {
			width: 200px;
			margin-bottom: 20px;
		}
		.button-group {
			display: inline-block;
			float: right;
		}
		.pagination-container {
			margin-top: 40px;
		}
	}
</style>
